package v1

import (
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type GetOptions struct {
	Filter
}

type UpdateOptions struct {
	Filter
}

type CreateOptions struct {
}

type DeleteOptions struct {
	Filter
}

type ListOptions struct {
	Filter
	Page *Page
	Options
}

type CountOptions struct {
	Filter
}

type Filter struct {
	filter *bson.M
}

type Options struct {
	findOptions    *options.FindOptions
	findOneOptions *options.FindOneOptions
}

func (o *Options) SetFindOptions(opts *options.FindOptions) {
	o.findOptions = opts
}

func (o *Options) GetOptions() *options.FindOptions {
	return o.findOptions
}

func (f *Filter) SetFilter(filter *bson.M) {
	f.filter = filter
}

func (f *Filter) AddFilter(key string, value interface{}) {
	if f.filter == nil {
		f.filter = &bson.M{}
	}
	(*f.filter)[key] = value
}

func (f *Filter) GetFilter() bson.M {
	if f.filter == nil {
		f.filter = &bson.M{}
	}
	return *f.filter
}

func (lo *ListOptions) SetPage(current, size int64) {
	lo.Page = &Page{
		Current: current,
		Size:    size,
	}
}

func (lo *ListOptions) ResolveFindOptions() *options.FindOptions {
	findOptions := lo.GetOptions()
	if lo.Page != nil {
		skip := int64(0)
		if lo.Page.Current > 0 {
			skip = (lo.Page.Current - 1) * lo.Page.Size
		} else {
			lo.Page.Current += 1
		}
		if lo.Page.Size == 0 {
			lo.Page.Size = 100
		}
		findOptions.Skip = &skip
		findOptions.Limit = &lo.Page.Size
	}
	return findOptions
}

type Page struct {
	Current int64
	Size    int64
}
